#include <stdio.h>
#include <stdint.h>
#include "hb_ddr_oem.h"

#define DDR_DQ_MAP_SIZE	32

uint8_t xj3_dvb_dq_map[DDR_DQ_MAP_SIZE] = {
	0x2,0x1,0x7,0x0,0x5,0x3,0x4,0x6,
	0x3,0x6,0x7,0x5,0x0,0x4,0x1,0x2,
	0x4,0x0,0x1,0x2,0x7,0x3,0x6,0x5,
	0x3,0x7,0x2,0x6,0x0,0x4,0x5,0x1,
};
uint8_t xj3_cvb_dq_map[DDR_DQ_MAP_SIZE] = {
	0x3,0x4,0x0,0x1,0x7,0x6,0x5,0x2,
	0x7,0x0,0x5,0x6,0x4,0x3,0x2,0x1,
	0x1,0x3,0x4,0x0,0x5,0x6,0x7,0x2,
	0x3,0x6,0x7,0x2,0x1,0x4,0x5,0x0,
};
uint8_t xj3_customer_board_dq_map[DDR_DQ_MAP_SIZE] = {
	0x1,0x0,0x7,0x2,0x6,0x5,0x4,0x3,
	0x4,0x6,0x7,0x3,0x2,0x5,0x1,0x0,
	0x7,0x3,0x0,0x4,0x5,0x1,0x2,0x6,
	0x3,0x2,0x5,0x0,0x1,0x6,0x4,0x7,
};

uint8_t *dqmap_array[] = {
	xj3_dvb_dq_map,
	xj3_cvb_dq_map,
	xj3_customer_board_dq_map,
	/*customer add dqmap*/
};

/*
 * package fccsp dqmap
 * cvb and sdb is not defined yet, use old package dqmap
 */
uint8_t xj3_dvb_dq_map_fccsp[DDR_DQ_MAP_SIZE] = {
	0x2,0x1,0x7,0x0,0x5,0x3,0x4,0x6,
	0x5,0x6,0x7,0x3,0x0,0x4,0x1,0x2,
	0x4,0x0,0x1,0x2,0x6,0x3,0x7,0x5,
	0x7,0x4,0x2,0x6,0x0,0x3,0x5,0x1,
};
uint8_t xj3_cvb_dq_map_fccsp[DDR_DQ_MAP_SIZE] = {
	0x3,0x4,0x0,0x1,0x7,0x6,0x5,0x2,
	0x7,0x0,0x5,0x6,0x4,0x3,0x2,0x1,
	0x1,0x3,0x4,0x0,0x5,0x6,0x7,0x2,
	0x3,0x6,0x7,0x2,0x1,0x4,0x5,0x0,
};
uint8_t xj3_customer_board_dq_map_fccsp[DDR_DQ_MAP_SIZE] = {
	0x1,0x0,0x7,0x2,0x6,0x5,0x4,0x3,
	0x4,0x6,0x7,0x3,0x2,0x5,0x1,0x0,
	0x7,0x3,0x0,0x4,0x5,0x1,0x2,0x6,
	0x3,0x2,0x5,0x0,0x1,0x6,0x4,0x7,
};

uint8_t *dqmap_array_fccsp[] = {
	xj3_dvb_dq_map_fccsp,
	xj3_cvb_dq_map_fccsp,
	xj3_customer_board_dq_map_fccsp,
	/*customer add dqmap*/
};
int32_t hb_add_dqmap(char *file, enum boot_mode mode)
{
	FILE *fp = NULL;
	uint32_t i = 0, j = 0;
	uint32_t file_size = 0;
	uint32_t padding_size = 0;
	char padding_value = 0;
	
	fp = fopen(file, "r");
	if (NULL == fp) {
		printf("File open fail!\n");
		return -1;
	}
	fseek(fp, 0, SEEK_END);
	file_size = ftell(fp);
	fclose(fp);
	fp = fopen(file, "ab+");
	if (NULL == fp) {
		printf("File open fail!\n");
		return -1;
	}
	padding_size = 512 - DDR_DQ_MAP_SIZE;
	for (i = 0; i < sizeof(dqmap_array) / sizeof(dqmap_array[0]); i++) {
		if (mode == BOOT_STORAGE)
			hdr_ddr.dqmap_addr[i] = file_size + i * 512;
		else if (mode == BOOT_UART)
			hdr_uart.dqmap_addr[i] = file_size + i * 512 - ALIGN_512(sizeof(hdr_uart));
		else
			printf("error boot mode!!!!\n");
		fwrite(dqmap_array[i], 1, DDR_DQ_MAP_SIZE, fp);
		for (j = 0; j < padding_size; j++) {
			fwrite(&padding_value, 1, 1, fp);
		}
		if (mode == BOOT_UART) {
			printf("dqmap addr[%d]:0x%x\n", i, hdr_uart.dqmap_addr[i]);
		
		}
	}
	if (mode == BOOT_STORAGE)
		file_size =  hdr_ddr.dqmap_addr[i - 1] + 512;
	else if (mode == BOOT_UART)
		file_size = hdr_uart.dqmap_addr[i - 1] + 512 + ALIGN_512(sizeof(hdr_uart));
	
	for (i = 0; i < sizeof(dqmap_array_fccsp) / sizeof(dqmap_array_fccsp[0]); i++) {
		if (mode == BOOT_STORAGE)
			hdr_ddr.dqmap_addr_fccsp[i] = file_size + i * 512;
		else if (mode == BOOT_UART)
			hdr_uart.dqmap_addr_fccsp[i] = file_size + i * 512 - ALIGN_512(sizeof(hdr_uart));
		else
			printf("error boot mode!!!!\n");
		fwrite(dqmap_array_fccsp[i], 1, DDR_DQ_MAP_SIZE, fp);
		for (j = 0; j < padding_size; j++) {
			fwrite(&padding_value, 1, 1, fp);
		}
		if (mode == BOOT_UART) {
			printf("dqmap fsscp addr[%d]:0x%x\n", i, hdr_uart.dqmap_addr_fccsp[i]);
		}
	}
	fclose(fp);
	return -1;
}
